package org.hawk.redis;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Tuple;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections4.MapUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hawk.os.HawkException;
import org.hawk.os.HawkOSOperator;

/**
 * 封装集群的操作.
 * @author jiangmin
 *
 */
public class HawkRedisClusterSession {
    private static final Logger logger = LogManager.getLogger(HawkRedisSession.class);
    /**
     * redis 客户端连接池
     */
    private JedisCluster jedisCluster;

    /**
     * 初始化redis客户端
     *
     * @param addr
     * @param port
     * @param timeout
     * @param password 可以为null
     * @param config   可以为null
     * @return
     */
    public boolean init(String addr, int port, int timeout, String password, HawkRedisPoolConfig config) {
        HostAndPort hostAndPort = new HostAndPort(addr, port);
        if (jedisCluster == null) {
            try {
                if (config == null) {
                    config = new HawkRedisPoolConfig();
                }

                if (HawkOSOperator.isEmptyString(password)) {
                    jedisCluster = new JedisCluster(hostAndPort, timeout, config);
                } else {                    
                    //这个5我是看源码里面的默认值,所以直接拿的.
                    jedisCluster = new JedisCluster(hostAndPort, timeout, timeout, 5, password, config);
                }

                Map<String, JedisPool> nodeMap = jedisCluster.getClusterNodes();
                if (MapUtils.isEmpty(nodeMap)) {
                    logger.error("jedis cluster init failed, addr: {}, port: {}", addr, port);
                    return false;
                } 

                logger.info("redis info:host={},port={},timeout={}ms,password={}, node:{}", addr, port, timeout, password, nodeMap);
                return true;
            } catch (Exception e) {
                HawkException.catchException(e);
            }
        }
        return false;
    }

    /**
     * 将 key 中储存的数值增加1
     *
     * @param key
     * @return
     */
    public long increase(String key) {
        try  {
            return jedisCluster.incr(key);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return 0;
    }

    /**
     * 字段增加
     *
     * @param key
     * @param add
     * @param expireSeconds
     * @return
     */
    public long increaseBy(String key, long add, int expireSeconds) {
        try{                                   
            Long value = jedisCluster.incrBy(key, add);
            this.expire(key, expireSeconds);
            return value;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return 0;
    }

    /**
     * 获取key对应的值
     */
    public String getString(String key) {
        return getString(key, 0);
    }

    /**
     * 获取key对应的值
     */
    public String getString(String key, int expireSeconds) {
        try{                       
            String value = jedisCluster.get(key);
            this.expire(key, expireSeconds);
            return value;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return null;
    }

    /**
     * 获取key对应的值
     */
    public byte[] getBytes(byte[] key, int expireSeconds) {
        try  {                                    
            byte[] value = jedisCluster.get(key);
            this.expire(key, expireSeconds);
            return value;
        } catch (Exception e) {
            HawkException.catchException(e);
        }

        return null;
    }

    /**
     * 获取key对应的值
     */
    public byte[] getBytes(byte[] key) {
        return getBytes(key, 0);
    }

    /**
     * 设置key的值
     *
     * @param key
     * @param value
     * @return
     */
    public boolean setString(String key, String value) {
        return setString(key, value, 0);
    }

    /**
     * 设置key的值
     *
     * @param key
     * @param value
     * @return
     */
    public boolean setBytes(String key, byte[] value) {
        return setBytes(key, value, 0);
    }

    /**
     * 设置key的值，并设置过期时间
     *
     * @param key
     * @param value
     * @return
     */
    public boolean setString(String key, String value, int expireSeconds) {
        String ret = null;
        try {            
            if (expireSeconds > 0) {
                ret = jedisCluster.setex(key, expireSeconds, value);
            } else {
                ret = jedisCluster.set(key, value);
            }            
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return ret != null;
    }

    /**
     * 设置key的值，并设置过期时间
     *
     * @param key
     * @param value
     * @return
     */
    public boolean setBytes(String key, byte[] value, int expireSeconds) {                
        String ret = null;
        try {
            if (expireSeconds > 0) {
                ret = jedisCluster.setex(key.getBytes(), expireSeconds, value);
            } else {
                ret = jedisCluster.set(key.getBytes(), value);
            }            
        } catch (Exception e) {
            HawkException.catchException(e);
        }         
        return ret != null;
    }

    /**
     * 存在key
     *
     * @param key
     * @return
     */
    public boolean exists(String key) {
        try {
            return jedisCluster.exists(key);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return false;
    }

    /**
     * 删除key
     *
     * @param key
     * @return
     */
    public boolean delete(String key, boolean bytes) {
        Long ret = null;
        try {
            if (bytes) {
                ret = jedisCluster.del(key.getBytes());
            } else {
                ret = jedisCluster.del(key);
            }
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        if (ret == null) {
            return false; 
        } else {
            return ret.intValue() > 0;
        }
    }

    /**
     * 删除key
     *
     * @param key
     * @return
     */
    public long del(String key) {
        try {
            return jedisCluster.del(key);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return 0;        
    }

    /**
     * 删除key
     *
     * @param key
     * @return
     */
    public long del(byte[] key) {
        try {
            return jedisCluster.del(key);
        } catch (Exception e) {
            HawkException.catchException(e);
        }        
        return 0;
    }

    /**
     * 获取哈希表key中指定域对应的值
     */
    public boolean expire(String key, int expireSeconds) {
        try {
            if (expireSeconds > 0) {
                jedisCluster.expire(key, expireSeconds);
            }            
            return true;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return false;        
    }
    
    public boolean expire(byte[] key, int expireSeconds) {
        try {
            if (expireSeconds > 0) {
                jedisCluster.expire(key, expireSeconds);
            }
            return true;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return false;
    }

    /**
     * 获取哈希表key中指定域对应的值
     */
    public String hGet(String key, String field, int expireSeconds) {
        String ret = null;
        try {
            
            ret = jedisCluster.hget(key, field);
            this.expire(key, expireSeconds);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return ret;        
    }

    /**
     * 获取哈希表key中指定域对应的值
     */
    public String hGet(String key, String field) {
        return hGet(key, field, 0);
    }

    /**
     * 获取哈希表key中指定域对应的值
     *
     * @param key
     * @param field
     * @return
     */
    public byte[] hGetBytes(String key, String field) {
        try {
            return jedisCluster.hget(key.getBytes(), field.getBytes());
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return null;
    }

    public byte[] hGetBytes(String key, String field, int expireSeconds) {
        byte[] bytes = null;
        try {
            byte[] keyBytes = key.getBytes();
            bytes = jedisCluster.hget(keyBytes, field.getBytes());
            this.expire(keyBytes, expireSeconds);
        } catch (Exception e) {
            HawkException.catchException(e);
        }        
        return bytes;
    }

    /**
     * 获取哈希表key中指定域对应的值
     *
     * @param key
     * @param field
     * @return
     */
    public Map<byte[], byte[]> hGetAllBytes(byte[] key) {
        try {
            return jedisCluster.hgetAll(key);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return null;
    }

    public Map<byte[], byte[]> hGetAllBytes(byte[] key, int expireSeconds) {
        Map<byte[], byte[]> bytesMap = null;
        try {
            bytesMap = jedisCluster.hgetAll(key);
            this.expire(key, expireSeconds);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return bytesMap;
    }

    /**
     * 获取哈希表key中所有域对应的值
     */
    public List<String> hVals(String key, int expireSeconds) {
        List<String>  strList = Collections.emptyList();
        try {
            strList = jedisCluster.hvals(key);
            this.expire(key, expireSeconds);
        } catch (Exception e) {
            HawkException.catchException(e);
        }        
        return strList;
    }

    /**
     * 获取哈希表key中所有域对应的值
     */
    public List<String> hVals(String key) {
        return hVals(key, 0);
    }

    /**
     * 获取哈希表key中所有域对应的值
     *
     * @param key
     * @return
     */
    public List<byte[]> hValsBytes(String key) {
        try {
            return new ArrayList<>(jedisCluster.hvals(key.getBytes()));
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return Collections.emptyList();
    }

    /**
     * 获取哈希表key中所有的域和对应的值
     *
     * @param key
     * @return
     */
    public Map<String, String> hGetAll(String key, int expireSeconds) {
        Map<String, String> retMap = new HashMap<>();
        try {
             retMap = jedisCluster.hgetAll(key);
             this.expire(key, expireSeconds);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return retMap;
    }

    /**
     * 获取哈希表key中所有的域和对应的值
     *
     * @param key
     * @return
     */
    public Map<String, String> hGetAll(String key) {
        return hGetAll(key, 0);
    }

    /**
     * 获取哈希表key中多个域的值
     *
     * @param key
     * @param fields
     * @return
     */
    public List<String> hmGet(String key, String... fields) {
        try {
            return jedisCluster.hmget(key, fields);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return Collections.emptyList();
    }

    public List<String> hmGet(String key, int expireSeconds, String... fields) {
        List<String> fieldValueList = new ArrayList<>();
        try {
            fieldValueList = jedisCluster.hmget(key, fields);
            this.expire(key, expireSeconds);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return fieldValueList;
    }

    /**
     * 获取哈希表key中多个域的值
     *
     * @param key
     * @param fields
     * @return
     */
    public List<byte[]> hmGet(byte[] key, byte[]... fields) {        
        try {
            return jedisCluster.hmget(key, fields);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return Collections.emptyList();
    }

    /**
     * 设置哈希表key中多个域的值
     *
     * @param key
     * @param hash
     * @param expireSeconds
     * @return
     */
    public boolean hmSet(String key, Map<String, String> hash, int expireSeconds) {
        try {
           String ret = jedisCluster.hmset(key, hash);
           this.expire(key, expireSeconds);
           return ret.equals("OK");
        } catch (Exception e) {
            HawkException.catchException(e);
        }        
        return false;
    }

    /**
     * 设置哈希表key中多个域的值
     *
     * @param key
     * @param hash
     * @param expireSeconds
     * @return
     */
    public boolean hmSetBytes(String key, Map<byte[], byte[]> hash, int expireSeconds) {
        try {
            byte[] keyBytes = key.getBytes();
            String ret = jedisCluster.hmset(keyBytes, hash);
            this.expire(keyBytes, expireSeconds);
            return ret.equals("OK");
        } catch (Exception e) {
            HawkException.catchException(e);
        }        
        return false;
    }

    /**
     * 设值哈希表key中指定域的值
     */
    public long hSet(String key, String field, String value, int expireSeconds) {
        try {
            Long ret = jedisCluster.hset(key, field, value);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1l;        
    }

    /**
     * 设值哈希表key中指定域的值
     * 返回-1表示失败
     */
    public long hSet(String key, String field, String value) {
        return hSet(key, field, value, 0);
    }

    /**
     * 设值哈希表key中指定域的值
     * 返回-1表示失败
     */
    public long hSetBytes(String key, String field, byte[] value) {
        return hSetBytes(key, field, value, 0);
    }

    /**
     * 设值哈希表key中指定域的值
     * 返回-1表示失败
     */
    public long hSetBytes(String key, String field, byte[] value, int expireSeconds) {
        return hSetBytes(key.getBytes(), field.getBytes(), value, expireSeconds);
    }

    public long hSetBytes(byte[] key, byte[] field, byte[] value, int expireSeconds) {
        try {
            long ret = jedisCluster.hset(key, field, value);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1L;               
    }

    /**
     * 删除哈希表 key 中中指定的域
     * 返回-1表示失败
     *
     * @param key
     * @return
     */
    public Long hDel(String key, String... field) {
        try {
            return jedisCluster.hdel(key, field);
        } catch (Exception e) {
            HawkException.catchException(e);
        }        
        return -1L;
    }

    /**
     * 删除哈希表 key 中中指定的域
     * 返回-1表示失败
     *
     * @param key
     * @param field
     * @return
     */
    public long hDelBytes(String key, byte[]... bytes) {
        try {
            
            return jedisCluster.hdel(key.getBytes(), bytes);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1L;               
    }

    /**
     * 设值哈希表key中指定域的值
     */
    public long hSetNx(String key, String field, String value) {
        try {
            return jedisCluster.hsetnx(key, field, value);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1L;
    }

    public long hSetNx(String key, String field, String value, int expireSeconds) {
        try {
            long ret = jedisCluster.hsetnx(key, field, value);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1L;
    }

    /**
     * 获取哈希表 key 中域的数量
     *
     * @param key
     * @return
     */
    public long hLen(String key, boolean bytes) {
        try {
            if (bytes) {
                return jedisCluster.hlen(key.getBytes());
            } else {
                return jedisCluster.hlen(key);
            }
        } catch (Exception e) {
            HawkException.catchException(e);
        }               
        return 0;
    }

    /**
     * 获取哈希表key中所有的field域
     *
     * @param key
     * @return
     */
    public Set<String> hKeys(String key, int expireSeconds) {
        try {
            Set<String> stringSet = jedisCluster.hkeys(key);
            this.expire(key, expireSeconds);
            return stringSet;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return Collections.emptySet();        
    }

    /**
     * 查看哈希表 key 中，是否存在给定的field域
     *
     * @param key
     * @return
     */
    public Boolean hExists(String key, String field, int expireSeconds) {
        try {
            Boolean ret = jedisCluster.hexists(key, field);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return Boolean.FALSE;        
    }

    /**
     * 为哈希表 key 中的域 field 的值加上增量 value
     *
     * @return
     */
    public Long hIncrBy(String key, String field, long value) {
        try {
             return jedisCluster.hincrBy(key, field, value);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return null;        
    }

    /**
     * 为哈希表 key 中的域 field 的值加上增量 value，并设置过期时间
     *
     * @param key
     * @param field
     * @param value
     * @param expireSeconds
     * @return
     */
    public boolean hIncrBy(String key, String field, int value, int expireSeconds) {
        try {
            if (jedisCluster.hincrBy(key, field, value) > 0) {
                this.expire(key, expireSeconds);
                return true;
            }
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return false;        
    }

    /**
     * 设置 key 的值，并将其生存时间设为 seconds (以秒为单位)
     *
     * @param key
     * @param seconds
     * @param value
     * @return
     */
    public boolean setEx(String key, int seconds, String value) {
        try {
            jedisCluster.setex(key, seconds, value);
            return true;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return false;
    }

    /**
     * 设置 key 的值，并将其生存时间设为 seconds (以秒为单位)
     *
     * @param key
     * @param seconds
     * @param bytes
     * @return
     */
    public boolean setBytesEx(String key, int seconds, byte[] bytes) {
        try {
            jedisCluster.setex(key.getBytes(), seconds, bytes);
            return true;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return false;
    }

    /**
     * 获取列表 key 中指定区间内的元素
     *
     * @return
     */
    public List<String> lRange(String key, long start, long end, int expireSeconds) {
        try {
            List<String> retList = jedisCluster.lrange(key, start, end);
            this.expire(key, expireSeconds);
            return retList;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return new ArrayList<String>();
    }

    /**
     * 获取列表 key 中指定区间内的元素
     *
     * @return
     */
    public List<byte[]> lRange(byte[] key, long start, long end, int expireSeconds) {
        try {
            List<byte[]> retList = jedisCluster.lrange(key, start, end);
            this.expire(key, expireSeconds);
            return retList;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return new ArrayList<>();
    }

    /**
     * 更新列表 key中下标为 index 的元素值
     *
     * @param key
     * @param index
     * @param value
     * @return
     */
    public String lSet(String key, long index, String value) {
        try {
            return jedisCluster.lset(key, index, value);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return null;        
    }

    /**
     * 向列表 key 的表尾(最右边)插入元素
     *
     * @param key
     * @param value
     * @return
     */
    public Long rPush(String key, int expireSeconds, String... value) {
        try {
            Long ret = jedisCluster.rpush(key, value);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1L;               
    }

    /**
     * 向列表 key 的表尾(最右边)插入元素
     *
     * @param key
     * @param value
     * @return
     */
    public long rPushBytes(String key, byte[]... value) {
        try {
            return jedisCluster.rpush(key.getBytes(), value);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1l;
    }

    /**
     * 向列表 key 的表头插入元素
     *
     * @param key
     * @param value
     * @return
     */
    public Long lPush(byte[] key, int expireSeconds, byte[]... value) {
        try {
            Long ret = jedisCluster.lpush(key, value);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1L;              
    }

    /**
     * 获取列表的长度
     *
     * @param key
     * @param value
     * @return
     */
    public long lLen(String key) {
        try {
            return jedisCluster.llen(key);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1;        
    }

    /**
     * 获取列表的长度
     *
     * @param key
     * @param value
     * @return
     */
    public Long lLen(byte[] key, int expireSeconds) {
        try {
            Long ret = jedisCluster.llen(key);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1l;        
    }

    /**
     * 向列表 key 的表头插入元素，并设置过期时间
     *
     * @param key
     * @param value
     * @return
     */
    public Long lPush(String key, int expireSeconds, String... value) {
        try {
            Long ret = jedisCluster.lpush(key, value);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1l;        
    }

    /**
     * 移除并返回列表 key 的头元素
     *
     * @param key
     * @param bytes
     * @return
     */
    public void lPop(String key, boolean bytes) {
        try {
            if (bytes) {
                jedisCluster.lpop(key.getBytes());
            } else {
                jedisCluster.lpop(key);
            }            
        } catch (Exception e) {
            HawkException.catchException(e);
        }        
    }

    /**
     * 对列表进行修剪(trim)，让列表只保留指定区间内的元素，不在指定区间之内的元素都将被删除
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public String lTrim(String key, long start, long end) {
        try {
            return jedisCluster.ltrim(key, start, end);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return null;        
    }

    /**
     * 对列表进行修剪(trim)，让列表只保留指定区间内的元素，不在指定区间之内的元素都将被删除
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public String lTrim(byte[] key, long start, long end, int expireSeconds) {
        try {
            String ret = jedisCluster.ltrim(key, start, end);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return null;        
    }

    /**
     * 根据参数 count 的值，移除列表中与参数 value 相等的元素
     *
     * @param key
     * @param count
     * @param value
     * @return
     */
    public Long lRem(String key, int count, String value) {
        try {
            return jedisCluster.lrem(key, count, value);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return null;        
    }

    /**
     * 获取列表 key 中，下标为 index 的元素
     *
     * @param key
     * @param index
     * @return
     */
    public String lIndex(String key, long index) {
        try {
           return jedisCluster.lindex(key, index);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return null;        
    }

    /**
     * 获取有序集 key 中， score 值介于 max 和 min 之间(默认包括等于 max 或 min )的所有的成员。有序集成员按 score
     * 值递减(从大到小)的次序排列
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public Set<Tuple> zRevrangeWithScores(String key, long start, long end, int expireSeconds) {
        try {
            Set<Tuple> ret = jedisCluster.zrevrangeWithScores(key, start, end);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return Collections.emptySet();        
    }

    /**
     * 获取有序集 key 中， score 值介于 max 和 min 之间(默认包括等于 max 或 min )的所有的成员。有序集成员按 score
     * 值递减(从小到大)的次序排列
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public Set<Tuple> zRangeWithScores(String key, long start, long end, int expireSeconds) {
        try {
            Set<Tuple> ret = jedisCluster.zrangeWithScores(key, start, end);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return Collections.emptySet();               
    }

    /**
     * 获取有序集 key 中，指定区间内的成员，其中成员的位置按 score 值递增(从小到大)来排序
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public Set<String> zRange(String key, long start, long end, int expireSeconds) {
        try {
            Set<String> ret = jedisCluster.zrange(key, start, end);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return Collections.emptySet();        
        
    }

    /**
     * 获取有序集 key 中，指定区间内的成员，其中成员的位置按 score 值递增(从大到小)来排序
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public Set<String> zRevRange(String key, long start, long end, int expireSeconds) {
        try {
            Set<String> ret = jedisCluster.zrevrange(key, start, end);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return Collections.emptySet();               
    }

    /**
     * 获取有序集 key 中，指定区间内的成员，其中成员的位置按 score 值递增(从大到小)来排序
     *
     * @param keyBytes
     * @param start
     * @param end
     * @return
     */
    public Set<byte[]> zRevRange(byte[] keyBytes, long start, long end, int expireSeconds) {
        try {
            Set<byte[]> ret = jedisCluster.zrevrange(keyBytes, start, end);
            this.expire(keyBytes, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return Collections.emptySet();
    }

    /**
     * 获取有序集 key 中，所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score
     * 值递增(从小到大)次序排列
     *
     * @param key
     * @param min
     * @param max
     * @return
     */
    public Set<String> zRangeByScore(String key, long min, long max, int expireSeconds) {
        try {
            Set<String> ret = jedisCluster.zrangeByScore(key, min, max);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return Collections.emptySet();               
    }

    /**
     * 获取有序集 key 中，所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score
     * 值递增(从小到大)次序排列
     *
     * @param key
     * @param min
     * @param max
     * @return
     */
    public Set<byte[]> zRangeByScore(byte[] key, long min, long max, int expireSeconds) {
        try {
            Set<byte[]> ret = jedisCluster.zrangeByScore(key, min, max);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return Collections.emptySet();        
    }

    /**
     * 获取有序集 key 中成员 member 的排名。其中有序集成员按 score 值递减(从小到大)排序
     *
     * @param key
     * @param member
     * @return
     */
    public Long zRank(String key, String member) {
        try {
            return jedisCluster.zrank(key, member);
        } catch (Exception e) {
            HawkException.catchException(e);
        }        
        return -1L;
    }

    /**
     * 获取有序集 key 中成员 member 的排名。其中有序集成员按 score 值递减(从大到小)排序
     *
     * @param key
     * @param member
     * @return
     */
    public Long zrevrank(String key, String member, int expireSeconds) {
        try {
            Long ret = jedisCluster.zrevrank(key, member);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1L;               
    }

    /**
     * 获取有序集 key 中，成员 member 的 score 值
     *
     * @param key
     * @param member
     * @return
     */
    public Double zScore(String key, String member, int expireSeconds) {
        try {
            Double ret = jedisCluster.zscore(key, member);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return 0D;        
    }

    /**
     * 移除有序集 key 中的一个或多个成员
     *
     * @param key
     * @param members
     */
    public Long zRem(String key, int expireSeconds, String... members) {
        try {
            Long ret = jedisCluster.zrem(key, members);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return 0L;        
    }

    /**
     * 移除有序集 key 中的一个或多个成员
     *
     * @param key
     * @param members
     */
    public Long zRem(byte[] key, byte[]... members) {
        try {
            return jedisCluster.zrem(key, members);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return 0L;               
    }

    /**
     * 将member 元素及其 score 值加入到有序集 key当中
     *
     * @param key
     * @param score
     * @param member
     */
    public Long zAdd(String key, double score, String member, int expireSeconds) {
        try {
            Long ret = jedisCluster.zadd(key, score, member);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1L;               
    }

    /**
     * 将member 元素及其 score 值加入到有序集 key当中
     *
     * @param key
     * @param score
     * @param member
     */
    public Long zAdd(String key, double score, String member) {
        return zAdd(key, score, member, 0);
    }

    /**
     * 将member 元素及其 score 值加入到有序集 key当中
     *
     * @param key
     * @param score
     * @param member
     */
    public Long zAdd(byte[] key, double score, byte[] member, int expireSeconds) {
        try {
            Long ret = jedisCluster.zadd(key, score, member);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }        
        return -1L;
    }

    /**
     * 将member 元素及其 score 值加入到有序集 key当中
     *
     * @param key
     * @param score
     * @param member
     */
    public Long zAdd(byte[] key, double score, byte[] member) {
        return zAdd(key, score, member, 0);
    }

    /**
     * 将members 加入到key当中
     *
     * @param key
     * @param members
     */
    public Long zAdd(String key, Map<String, Double> members, int expireSeconds) {
        try {
            Long ret = jedisCluster.zadd(key, members);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1L;               
    }

    /**
     * 将members 加入到key当中
     *
     * @param key
     * @param members
     */
    public Long zAdd(String key, Map<String, Double> members) {
        return zAdd(key, members, 0);
    }

    /**
     * 获取有序集 key 中， score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量
     *
     * @param key
     * @param min
     * @param max
     */
    public Long zCount(String key, long min, long max) {
        try {
            return jedisCluster.zcount(key, min, max);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return 0L;               
    }

    /**
     * 获取有序集 key 中， score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量
     *
     * @param key
     * @param min
     * @param max
     */
    public Long zCount(byte[] key, long min, long max) {
        try {
            return jedisCluster.zcount(key, min, max);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return 0L;               
    }

    /**
     * 移除有序集 key中，指定排名(rank)区间内的所有成员
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public Long zRemrangeByRank(String key, long start, long end) {
        try {
            return jedisCluster.zremrangeByRank(key, start, end);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1L;               
    }

    /**
     * 移除有序集 key中，指定排名(rank)区间内的所有成员
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public Long zRemrangeByRank(byte[] key, long start, long end) {
        try {
            return jedisCluster.zremrangeByRank(key, start, end);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1L;               
    }

    /**
     * 为有序集key的成员member的score值加上增量increament
     *
     * @param key
     * @param member
     * @param increament
     * @param expireSeconds
     * @return
     */

    public Double zIncrby(String key, String member, double increament, int expireSeconds) {
        try {
            Double ret = jedisCluster.zincrby(key, increament, member);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return 0D;               
    }

    /**
     * 移除集合 key 中的一个或多个 member 元素
     *
     * @param key
     * @param members
     * @return
     */
    public Long sRem(String key, String... members) {
        try {
            return jedisCluster.srem(key, members);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return -1L;               
    }

    /**
     * 获取集合 key 中的所有成员
     *
     * @param key
     * @return
     */
    public Set<String> sMembers(String key) {
        try {
            return jedisCluster.smembers(key);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return Collections.emptySet();               
    }

    public Set<String> sMembers(String key, int expireSeconds) {
        try {
           Set<String> ret = jedisCluster.smembers(key);
           this.expire(key, expireSeconds);
           return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return Collections.emptySet();               
    }

    /**
     * 将一个或多个 member 元素加入到集合 key 当中
     *
     * @param key
     * @param members
     * @return
     */
    public Long sAdd(String key, int expireSeconds, String... members) {
        try {
            Long ret = jedisCluster.sadd(key, members);
            this.expire(key, expireSeconds);
            return ret;
        } catch (Exception e) {
            HawkException.catchException(e);
        }        
        return 0L;
    }

    /**
     * 将一个或多个 member 元素加入到集合 key 当中
     *
     * @param key
     * @param members
     * @return
     */
    public Long sadd(String key, String... members) {
        try {
            return jedisCluster.sadd(key, members);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return 0L;        
    }

    /** 随机取一个元素，并从列表删除 */
    public String spop(String key) {
        try {
            return jedisCluster.spop(key);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return "";        
    }

    /**
     * 获取集合的成员数
     *
     * @param key
     * @return
     */
    public long sCard(String key) {
        try {
            return jedisCluster.scard(key);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return 0L;               
    }

    /**
     * 判断member元素是否是集合key的成员
     *
     * @param key
     * @param member
     * @return
     */
    public Boolean sIsmember(String key, String member) {
        try {
            return jedisCluster.sismember(key, member);
        } catch (Exception e) {
            HawkException.catchException(e);
        }
        return false;               
    }
    
    /**
     * 设值key的值,如果不存在,则set并返回1
     */
    public long setNx(String key, String value) {        
        
        try {
            return jedisCluster.setnx(key, value);
        } catch (Exception e) {
            HawkException.catchException(e);
        } 
        return -1L;
    }
    
    public JedisCluster getJedisCluster() {
        return jedisCluster;
    }    
}
